<template>
    <PeInput ref="datePickerRef" v-model="time" :id="id" :prefixIcon="Clock" :size="size" :placeholder="placeholder"
        :name="name" :disabled="disabled" :clearable="clearable" style="width: 200px;" @focus="focus" @blur="blur">
    </PeInput>
    <Popup v-model="show" ref="popupRef">
        <div class="pe-time-picker-box">
            <ScrollBar ref="hourRef">
                <ul class="pe-time-picker-list">
                    <li v-for="item in hourList" class="pe-time-picker-item" :class="item.isactive ? 'is-active' : ''"
                        @click="setTime(0, item.index)">{{ item.value
                        }}</li>
                </ul>
            </ScrollBar>
            <ScrollBar ref="minRef">
                <ul class="pe-time-picker-list">
                    <li v-for="item in minList" class="pe-time-picker-item" :class="item.isactive ? 'is-active' : ''"
                        @click="setTime(1, item.index)">{{ item.value
                        }}</li>
                </ul>
            </ScrollBar>
            <ScrollBar ref="secRef">
                <ul class="pe-time-picker-list">
                    <li v-for="item in secList" class="pe-time-picker-item" :class="item.isactive ? 'is-active' : ''"
                        @click="setTime(2, item.index)">{{ item.value
                        }}</li>
                </ul>
            </ScrollBar>
        </div>
        <div class="pe-time-picker-bottom">
            <PeButton type="primary" size="small" @click="sureClick">确定</PeButton>
            <PeButton size="small" @click="show = false">取消</PeButton>
        </div>
    </Popup>
</template>

<script setup lang="ts">
import { inject, nextTick, onMounted, ref, watch } from "vue"
import dayjs from "dayjs";
import PeInput from '../input/input.vue'
import Clock from "../../icons/clock.vue";
import ScrollBar from "../scrollbar/scrollbar.vue";
import PeButton from '../button/button.vue'
import { zero } from "../../utils/commonUtil";
import Popup from "../popup/popup.vue";

// 组件绑定值
const timeModel = defineModel<string | number>()
// 输入框绑定值
const time = ref<string>("")

/**
 * @param disabled 是否禁用
 * @param size 组件尺寸
 * @param readonly 是否只读
 * @param placeholder 输入框占位文本
 * @param clearable 是否可清空
 * @param name 输入框name
 * @param id 输入框id
 * @param format 输入框中的格式
 * @param valueFormat 绑定值格式
 */
interface Props {
    disabled?: boolean,
    size?: 'default' | 'large' | 'small',
    readonly?: boolean,
    placeholder?: string,
    clearable?: boolean,
    name?: string,
    id?: string,
    format?: string,
    valueFormat?: string
}

const props = withDefaults(defineProps<Props>(), {
    disabled: false,
    size: 'default',
    readonly: false,
    clearable: true,
    format: "HH:mm:ss",
    valueFormat: "HH:mm:ss"
})

const emits = defineEmits(['focus', 'blur', 'change'])

interface TimeList {
    index: number,
    value: string,
    isactive: boolean
}
let hourList = ref<Array<TimeList>>([])
let minList = ref<Array<TimeList>>([])
let secList = ref<Array<TimeList>>([])

// 选择框元素
const datePickerRef = ref<any>()
const popupRef = ref<any>()

// 时间选择滚动条ref
const hourRef = ref()
const minRef = ref()
const secRef = ref()

const activeHour = ref<string>("")
const activeMin = ref<string>("")
const activeSec = ref<string>("")

const date = `${new Date().getFullYear}-${zero(new Date().getMonth() + 1)}-${zero(new Date().getDate())}`
const timestamp = new Date(`${date} 00:00:00`).getTime()

onMounted(() => {
    popupRef.value?.setRef(datePickerRef.value)
    for (let i = 0; i < 24; i++) {
        hourList.value.push({ index: i, value: zero(i), isactive: false })
    }
    for (let i = 0; i < 60; i++) {
        minList.value.push({ index: i, value: zero(i), isactive: false })
        secList.value.push({ index: i, value: zero(i), isactive: false })
    }
    if (timeModel.value || timeModel.value === 0) {
        // 如果有默认值则计算时分秒
        if (typeof timeModel.value === 'number') {
            const temp = Math.floor(timeModel.value / 1000)
            if (temp <= 0) {
                activeHour.value = "00"
                activeMin.value = "00"
                activeSec.value = "00"
            } else {
                activeSec.value = zero(temp % 60)
                activeMin.value = zero(Math.floor(temp / 60))
                activeHour.value = zero(Math.floor(temp / 3600))
                time.value = dayjs(`${date} ${activeHour.value}:${activeMin.value}:${activeSec.value}`).format(props.valueFormat)
            }
        } else {
            time.value = dayjs(timestamp + timeModel.value).format("HH:mm:ss")
        }
    } else {
        // 如果没有默认值则为当前时间
        const date = new Date()
        const hour = date.getHours()
        const min = date.getMinutes()
        const sec = date.getSeconds()
        hourList.value.forEach(item => {
            if (item.index === hour) {
                item.isactive = true
                activeHour.value = item.value
            } else {
                item.isactive = false
            }
        })
        minList.value.forEach(item => {
            if (item.index === min) {
                item.isactive = true
                activeMin.value = item.value
            } else {
                item.isactive = false
            }
        })
        secList.value.forEach(item => {
            if (item.index === sec) {
                item.isactive = true
                activeSec.value = item.value
            } else {
                item.isactive = false
            }
        })
    }
    hourRef.value.$el.onscrollend = (event: any) => {
        setScrollTop(event, 0)
    }
    minRef.value.$el.onscrollend = (event: any) => {
        setScrollTop(event, 1)
    }
    secRef.value.$el.onscrollend = (event: any) => {
        setScrollTop(event, 2)
    }
})

// 点击时分秒数值
const setTime = (flag: number, index: number) => {
    if (flag === 0) {
        hourList.value.forEach(item => {
            if (item.index === index) {
                item.isactive = true
                activeHour.value = item.value
            } else {
                item.isactive = false
            }
        })
        hourRef.value.$el.scrollTop = index * 32
    } else if (flag === 1) {
        minList.value.forEach(item => {
            if (item.index === index) {
                item.isactive = true
                activeMin.value = item.value
            } else {
                item.isactive = false
            }
        })
        minRef.value.$el.scrollTop = index * 32
    } else if (flag === 2) {
        secList.value.forEach(item => {
            if (item.index === index) {
                item.isactive = true
                activeSec.value = item.value
            } else {
                item.isactive = false
            }
        })
        secRef.value.$el.scrollTop = index * 32
    }
    time.value = dayjs(`${date} ${activeHour.value}:${activeMin.value}:${activeSec.value}`).format(props.valueFormat)
}

// 点击确定按钮
const sureClick = () => {
    let temp
    if (typeof timeModel.value === 'number') {
        temp = (Number(activeHour.value) * 60 * 60 + Number(activeMin.value) * 60 + Number(activeSec.value)) * 1000
    } else {
        temp = dayjs(`${date} ${activeHour.value}:${activeMin.value}:${activeSec.value}`).format(props.valueFormat)
    }
    timeModel.value = temp
    emits("change", temp)
    show.value = false
}

/**
 * 获取时分秒滚动条位置
 * @param event 元素
 * @param flag 时分秒标志
 */
const setScrollTop = (event: any, flag: number) => {
    const scrollTop = event.target.scrollTop
    const temp = Math.round(scrollTop / 32)
    if (scrollTop % 32 !== 0) {
        event.target.scrollTop = temp * 32
    }
    if (flag === 0) activeHour.value = zero(temp)
    else if (flag === 1) activeMin.value = zero(temp)
    else if (flag === 2) activeSec.value = zero(temp)
    hourList.value.forEach(item => {
        if (item.value === activeHour.value) {
            item.isactive = true
        } else {
            item.isactive = false
        }
    })
    minList.value.forEach(item => {
        if (item.value === activeMin.value) {
            item.isactive = true
        } else {
            item.isactive = false
        }
    })
    secList.value.forEach(item => {
        if (item.value === activeSec.value) {
            item.isactive = true
        } else {
            item.isactive = false
        }
    })
    time.value = dayjs(`${date} ${activeHour.value}:${activeMin.value}:${activeSec.value}`).format(props.valueFormat)
}

// 下拉框显示标志
const show = ref<boolean>(false)
const zIndex = inject("pe-z-index", ref<number>(2000))
watch(show, newShow => {
    if (newShow) {
        zIndex.value++
    }
})

// 获取焦点
const focus = () => {
    show.value = true
    nextTick(() => {
        hourRef.value.$el.scrollTop = Number(activeHour.value) * 32
        minRef.value.$el.scrollTop = Number(activeMin.value) * 32
        secRef.value.$el.scrollTop = Number(activeSec.value) * 32
    })
    emits("focus")
}

// 失去焦点
const blur = () => {
    emits("blur")
}
</script>

<script lang="ts">
export default {
    name: "pe-time-picker"
}
</script>
